package cn.com.cifi.mars.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import lombok.extern.slf4j.Slf4j;

/**
 * 类名称：DateUtils 创建人：lee
 *
 * @version 1.0.0
 */
@Slf4j
public class DateUtils {

	/** 定义常量 **/
	public static final String DATE_FULL_STR = "yyyy-MM-dd HH:mm:ss";
	public static final String DATE_FULL_STR_S = "yyyy-MM-dd HH:mm:ss.SSS";
	public static final String DATE_SMALL_STR = "yyyy-MM-dd";
	public static final String DATE_JFP_STR = "yyyy-MM";
	public static final String DATE_KEY_FULL_STR_ONE = "yyyy/M/dd HH:mm:ss";
	public static final String DATE_KEY_FULL_STR_TWO = "yyyy/MM/dd HH:mm:ss";
	public static final String DATE_KEY_SMALL_STR = "yyyyMMdd";
	public static final String DATE_KEY_SMALL = "yyyyMM";

	/**
	 *
	 * 方法描述：日期类型转字符串
	 *
	 * @param date
	 * @param format
	 * @return String 创建人：yyd 创建时间：2019年9月9日 上午11:29:19
	 */
	public static String dateToString(Date date, String format) {
		String result = "";
		SimpleDateFormat formater = new SimpleDateFormat(format);
		try {
			result = formater.format(date);
		} catch (Exception e) {
			log.error("###### errorMsg: ", e);
		}
		return result;
	}

	/**
	 *
	 * 方法描述：字符串类型日期转日期
	 *
	 * @param
	 * @param
	 * @return String 创建人：yyd 创建时间：2019年9月9日 上午11:29:19
	 */
	public static Date strDateToDate(String strDate, String pattern) {
		Date date = null;
		SimpleDateFormat df = new SimpleDateFormat(pattern);
		try {
			date = df.parse(strDate);
		} catch (ParseException e) {
			log.error("###### errorMsg: ", e);
		}
		return date;
	}

	/**
	 * 获取指定日期的年份
	 *
	 * @param date util.Date日期
	 * @return int 年份
	 */
	public static int getYearOfDate(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.YEAR);
	}

	/**
	 * 获取指定日期的月份
	 *
	 * @param date
	 *            util.Date日期
	 * @return int 月份
	 */
	public static int getMonthOfDate(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.MONTH) + 1;
	}

	/**
	 * 获取指定日期的日份
	 *
	 * @param date
	 *            日期
	 * @return int 日份
	 */
	public static int getDayOfDate(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 获取指定日期的小时
	 *
	 * @param date
	 *            util.Date日期
	 * @return int 小时
	 */
	public static int getHourOfDate(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.HOUR_OF_DAY);
	}

	/**
	 * 获取指定日期的分钟
	 *
	 * @param date
	 *            util.Date日期
	 * @return int 分钟
	 */
	public static int getMinuteOfDate(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.MINUTE);
	}

	/**
	 * 获取指定日期的秒钟
	 *
	 * @param date
	 *            util.Date日期
	 * @return int 秒钟
	 */
	public static int getSecondOfDate(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.SECOND);
	}

	/**
	 *
	 * 方法说明：获取指定月份的工作日天数
	 *
	 * @param year
	 * @param month
	 * @return
	 * @author wangchaojie 2015年10月13日
	 *
	 */
	public static int getWorkDayByMonth(int year, int month) {
		List<Date> dates = new ArrayList<Date>();
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month - 1);
		cal.set(Calendar.DATE, 1);
		while (cal.get(Calendar.YEAR) == year && cal.get(Calendar.MONTH) < month) {
			int day = cal.get(Calendar.DAY_OF_WEEK);
			if (!(day == Calendar.SUNDAY || day == Calendar.SATURDAY)) {
				dates.add((Date) cal.getTime().clone());
			}
			cal.add(Calendar.DATE, 1);
		}
		return dates.size();
	}

	/**
	 * 获取精确到秒的时间戳
	 *
	 * @return
	 */
	public static int getSecondTimestamp(Date date) {
		if (null == date) {
			return 0;
		}
		String timestamp = String.valueOf(date.getTime());
		int length = timestamp.length();
		if (length > 3) {
			return Integer.valueOf(timestamp.substring(0, length - 3));
		} else {
			return 0;
		}
	}

	/**
	 *
	 * 方法描述：验证日期格式
	 *
	 * @param str
	 * @return boolean 创建人：yyd 创建时间：2019年9月9日 上午11:27:02
	 */
	public static boolean isValidDate(String str) {
		boolean convertSuccess = true;
		// 指定日期格式为四位年/两位月份/两位日期，注意yyyy/MM/dd区分大小写；
		SimpleDateFormat format = new SimpleDateFormat(DATE_SMALL_STR);
		try {
			// 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期，比如2007/02/29会被接受，并转换成2007/03/01
			format.setLenient(false);
			format.parse(str);
		} catch (ParseException e) {
			// log.error("###### errorMsg: ", e);
			// 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
			convertSuccess = false;
		}
		return convertSuccess;
	}

	/**
	 * 将日期字符串转换为LocalDateTime对象
	 *
	 * @param dateStr
	 *            如：2019-06-05
	 * @param dateTimeFormatter
	 * @return
	 */
	public static LocalDateTime parseDate(String dateStr, DateTimeFormatter dateTimeFormatter) {
		try {
			return LocalDateTime.of(LocalDate.parse(dateStr, dateTimeFormatter), LocalTime.MIN);
		} catch (Exception e) {
			log.error(e.getMessage());
			;
			return null;
		}
	}

	/**
	 * 讲LocalDateTime转换成string日期
	 * @param time
	 * @return
	 */
	public static String formatString(LocalDateTime time) {
		DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		String localTime = df.format(time);
		return localTime;
	}


	public static Date getBeginTime(int year, int month) {
        YearMonth yearMonth = YearMonth.of(year, month);
        LocalDate localDate = yearMonth.atDay(1);
        LocalDateTime startOfDay = localDate.atStartOfDay();
        ZonedDateTime zonedDateTime = startOfDay.atZone(ZoneId.of("Asia/Shanghai"));

        return Date.from(zonedDateTime.toInstant());
    }

    public static Date getEndTime(int year, int month) {
        YearMonth yearMonth = YearMonth.of(year, month);
        LocalDate endOfMonth = yearMonth.atEndOfMonth();
        LocalDateTime localDateTime = endOfMonth.atTime(23, 59, 59, 999);
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("Asia/Shanghai"));
        return Date.from(zonedDateTime.toInstant());
    }

    public static List<String> getMonthList(String start,String end){
		List<String> list = new ArrayList<String>();
		try {
			Date startDate = new SimpleDateFormat("yyyy-MM").parse(start);
			Date endDate = new SimpleDateFormat("yyyy-MM").parse(end);

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(startDate);
			// 获取开始年份和开始月份
			int startYear = calendar.get(Calendar.YEAR);
			int startMonth = calendar.get(Calendar.MONTH);
			// 获取结束年份和结束月份
			calendar.setTime(endDate);
			int endYear = calendar.get(Calendar.YEAR);
			int endMonth = calendar.get(Calendar.MONTH);
			//

			for (int i = startYear; i <= endYear; i++) {
				String date = "";
				if (startYear == endYear) {
					for (int j = startMonth; j <= endMonth; j++) {
						if (j < 9) {
							date = i + "-0" + (j + 1);
						} else {
							date = i + "-" + (j + 1);
						}
						list.add(date);
					}

				} else {
					if (i == startYear) {
						for (int j = startMonth; j < 12; j++) {
							if (j < 9) {
								date = i + "-0" + (j + 1);
							} else {
								date = i + "-" + (j + 1);
							}
							list.add(date);
						}
					} else if (i == endYear) {
						for (int j = 0; j <= endMonth; j++) {
							if (j < 9) {
								date = i + "-0" + (j + 1);
							} else {
								date = i + "-" + (j + 1);
							}
							list.add(date);
						}
					} else {
						for (int j = 0; j < 12; j++) {
							if (j < 9) {
								date = i + "-0" + (j + 1);
							} else {
								date = i + "-" + (j + 1);
							}
							list.add(date);
						}
					}

				}

			}

		} catch (Exception e) {
			log.error("###### errorMsg: ", e);
		}
		return list;
	}

	/**
	 * 将日期字符串转换为LocalDateTime对象
	 * @param dateStr 如：2019-06-05
	 * @param
	 * @return
	 */
	public static LocalDateTime parseDate(String dateStr, String dateFormat){
		DateTimeFormatter df = DateTimeFormatter.ofPattern(dateFormat);
		try {
			return LocalDateTime.of(LocalDate.parse(dateStr,df), LocalTime.MIN);
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * @Description: 将LocalDateTime对象转换为字符串
	 */
	public static String localDateTimeToString(LocalDateTime time, String dateFormat) {
		DateTimeFormatter df = DateTimeFormatter.ofPattern(dateFormat);
		return df.format(time);
	}


	/**
	 * 如果截止是期是当前月，则准确的截止时间是当前时间
	 * 如果截止日期不是当前月，如2020-02,则准确的截止时间是：2020-03-1 06:00:00
	 * @param endDate 2020-03
	 * @return
	 */
	public static String toEndTimeStr(String endDate){
		if (LocalDate.now().format(DateTimeFormatter.ofPattern(DATE_JFP_STR)).equals(endDate)){
			return LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATE_FULL_STR));
		}
		LocalDate localDate = LocalDate.parse(endDate + "-01", DateTimeFormatter.ISO_LOCAL_DATE);
		LocalTime localTime = LocalTime.of(6,0,0,0);
		return LocalDateTime.of(localDate,localTime).plusMonths(1).format(DateTimeFormatter.ofPattern(DATE_FULL_STR));
	}

	/**
	 * 是否日期
	 * @param date
	 * @return
	 */
	public static boolean isDate(String date){
		return StrUtils.isDate(date);
	}

	/**
	 * 字符转date
	 * @param str
	 * @return
	 */
	public static Date toDate(String str){
		//yyyy-MM-dd
		if (str.matches("\\d{4}-\\d{1,2}-\\d{1,2}")){
			return strDateToDate(str,DATE_SMALL_STR);
		}

		//yyyy-MM-dd HH:mm:ss
		if (str.matches("\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}")){
			return strDateToDate(str,DATE_FULL_STR);
		}

		return null;
	}

}
